package com.koc.robot;

import com.koc.robot.common.Vector;
import com.koc.robot.common.Vector3;

public class Block {
	public int mTileNum;	//indicate tile type, if 1, no Block
	static final int INVALID_TILENUM = 0;
	
	public int mFaceColor[];
	public int mGridColor[];
	public boolean mFaceVisiable[] = new boolean[5]; //total 5 faces.

	private Map mMap;
    
	private int mVertexBuffer[];
	
	public Block(Map map)
	{
		mTileNum = INVALID_TILENUM;
		mFaceColor = new int[]
				{
					Util.toColor(255, 0, 0), 
					Util.toColor(0, 255, 0),
					Util.toColor(0, 0, 255),
					Util.toColor(255, 255, 0),
					Util.toColor(255, 255, 255),
				};
		
		mGridColor = new int[]
				{
					Util.toColor(100, 100, 100),
					Util.toColor(150, 150, 150),
				};
		
		
		mMap = map;
    	mVertexBuffer = new int[Map.PRE_FACE_VERTEX_BUFFER_SIZE / 4];
 
	}
	
	public void draw(Vector3 pos, Scene scene)
	{
		if(mTileNum != INVALID_TILENUM)
		{
			Vector3 p1 = new Vector3(pos.x + scene.getRelPoint(0).x, 
					pos.y + scene.getRelPoint(0).y, pos.z);
			Vector3 p2 = new Vector3(pos.x + scene.getRelPoint(1).x, 
					pos.y + scene.getRelPoint(1).y, pos.z);
			Vector3 p3 = new Vector3(pos.x + scene.getRelPoint(2).x, 
					pos.y + scene.getRelPoint(2).y, pos.z);
			Vector3 p4 = new Vector3(pos.x + scene.getRelPoint(3).x, 
					pos.y + scene.getRelPoint(3).y, pos.z);
	
			//top face
			if(mFaceVisiable[4])
			{
				drawFace(scene, p1, p2, p3, p4, 4, 0);
			}
			
			int side1;
			int side2;
			Vector3 newPoint[] = new Vector3[6];
			
			float rotation = scene.getRotation();
			if(rotation > Common.PI_025 && rotation <= Common.PI_075) //side 0, 3
			{
				side1 = 0;
				side2 = 3;
				
				if(mFaceVisiable[side1] || mFaceVisiable[side2])
				{
					newPoint[0] = new Vector3(p2);
					newPoint[1] = new Vector3(p1);
					newPoint[2] = new Vector3(p4);
					
					newPoint[3] = new Vector3(newPoint[0].x, newPoint[0].y + scene.getBoxHeightModded(), newPoint[0].z);
					newPoint[4] = new Vector3(newPoint[1].x, newPoint[1].y + scene.getBoxHeightModded(), newPoint[1].z);
					newPoint[5] = new Vector3(newPoint[2].x, newPoint[2].y + scene.getBoxHeightModded(), newPoint[2].z);
				}
			}
			else if(rotation > Common.PI_175 || rotation <= Common.PI_025)
			{
				side1 = 1;
				side2 = 0;
				
				if(mFaceVisiable[side1] || mFaceVisiable[side2])
				{
					newPoint[0] = new Vector3(p3);
					newPoint[1] = new Vector3(p2);
					newPoint[2] = new Vector3(p1);
					
					newPoint[3] = new Vector3(newPoint[0].x, newPoint[0].y + scene.getBoxHeightModded(), newPoint[0].z);
					newPoint[4] = new Vector3(newPoint[1].x, newPoint[1].y + scene.getBoxHeightModded(), newPoint[1].z);
					newPoint[5] = new Vector3(newPoint[2].x, newPoint[2].y + scene.getBoxHeightModded(), newPoint[2].z);
				}
			}
			else if(rotation > Common.PI_125 && rotation <= Common.PI_175)
			{
				side1 = 2;
				side2 = 1;
				
				if(mFaceVisiable[side1] || mFaceVisiable[side2])
				{
					newPoint[0] = new Vector3(p4);
					newPoint[1] = new Vector3(p3);
					newPoint[2] = new Vector3(p2);
					
					newPoint[3] = new Vector3(newPoint[0].x, newPoint[0].y + scene.getBoxHeightModded(), newPoint[0].z);
					newPoint[4] = new Vector3(newPoint[1].x, newPoint[1].y + scene.getBoxHeightModded(), newPoint[1].z);
					newPoint[5] = new Vector3(newPoint[2].x, newPoint[2].y + scene.getBoxHeightModded(), newPoint[2].z);
				}
			}
			else // rotation > Common.PI_075 && rotation <= Common.PI_125
			{
				side1 = 3;
				side2 = 2;
				
				if(mFaceVisiable[side1] || mFaceVisiable[side2])
				{
					newPoint[0] = new Vector3(p1);
					newPoint[1] = new Vector3(p4);
					newPoint[2] = new Vector3(p3);
					
					newPoint[3] = new Vector3(newPoint[0].x, newPoint[0].y + scene.getBoxHeightModded(), newPoint[0].z);
					newPoint[4] = new Vector3(newPoint[1].x, newPoint[1].y + scene.getBoxHeightModded(), newPoint[1].z);
					newPoint[5] = new Vector3(newPoint[2].x, newPoint[2].y + scene.getBoxHeightModded(), newPoint[2].z);
				}
			}
			
			//side face
			if(mFaceVisiable[side1])
			{
				drawFace(scene, newPoint[0], newPoint[1], newPoint[4], newPoint[3], side1, 1);
			}
			if(mFaceVisiable[side2])
			{
				drawFace(scene, newPoint[1], newPoint[2], newPoint[5], newPoint[4], side2, 1);
			}
		}
			
	}
	
	private void drawFace(Scene scene, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, 
			int faceColorIdx, int gridColorIdx)
	{
		Util.writeFloatToIntBuffer(p1.x, mVertexBuffer, 0);
		Util.writeFloatToIntBuffer(p1.y, mVertexBuffer, 1);
		Util.writeFloatToIntBuffer(p1.z, mVertexBuffer, 2);
		Util.writeFloatToIntBuffer(p2.x, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 1);
		Util.writeFloatToIntBuffer(p2.y, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 1 + 1);
		Util.writeFloatToIntBuffer(p2.z, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 1 + 2);
		Util.writeFloatToIntBuffer(p3.x, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 2);
		Util.writeFloatToIntBuffer(p3.y, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 2 + 1);
		Util.writeFloatToIntBuffer(p3.z, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 2 + 2);
		Util.writeFloatToIntBuffer(p4.x, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 3);
		Util.writeFloatToIntBuffer(p4.y, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 3 + 1);	
		Util.writeFloatToIntBuffer(p4.z, mVertexBuffer, Map.PER_VERTEX_POINT_WORD_NUM * 3 + 2);	
		
		if(scene.isDrawFace())
		{
			int color = fadeColor(mFaceColor[faceColorIdx], scene.getMapFaceColorFader());

			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 0 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 1 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 2 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 3 + 3] = color;
			
			//IntBuffer buffer = IntBuffer.wrap(mVertexBuffer);
			//buffer.position(0);
			
	    	mMap.fillFaceVertexBuffer(mVertexBuffer);
		}
		if(scene.isDrawGrid())
		{
			int color = fadeColor(mGridColor[gridColorIdx], scene.getMapGridColorFader());	    	
			
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 0 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 1 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 2 + 3] = color;
			mVertexBuffer[Map.PER_VERTEX_POINT_WORD_NUM * 3 + 3] = color;
			
			//IntBuffer buffer = IntBuffer.wrap(mVertexBuffer);
			//buffer.position(0);
			
	    	mMap.fillGridVertexBuffer(mVertexBuffer);
		}
	}
	
	private int fadeColor(int c, float fader)
	{		
		return (((int)(((c >> 24) & 0xFF) * fader)) << 24) | (c & 0x00FFFFFF);		
	}
	
}
